---
sidebar_position: 3
---
import DisableColumns from '../../src/demos/disableColumns'

# Columns

Columns are simple objects and can be declared as such:
```tsx
const columns = [
  { title: 'A', id: 'a', /*...*/ },
  { title: 'B', id: 'b', /*...*/ },
]
```

## title
> Type: `JSX.Element`<br />
> Default: `null`

Element to display in the header row.

## id
> Type: `string`

You can specify a unique ID for each column. This allows you to specify the column ID instead of its index when [controlling the grid](../controlling-the-grid).

## Sizing
Sizing uses the [flexbox algorithm](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox#properties_applied_to_flex_items), checkout some [examples](../columns#responsive-width).

### basis
> Type: `number`<br />
> Default: `0`

Same as the [flex-basis property](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis). 
This is the initial width of the column in pixels before growing or shrinking to fit the grid width.

### grow
> Type: `number`<br />
> Default: `1`

Same as the [flex-grow property](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow). 
This is a unit-less factor that dictates how much this column should grow to occupy the entire available width of the grid.

### shrink
> Type: `number`<br />
> Default: `1`

Same as the [flex-shrink property](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink). 
This is a unit-less factor that dictates how much this column should shrink to fit to the available width of the grid.

### minWidth
> Type: `number`<br />
> Default: `100`

Minimum width of the column in pixels. Can be `0` for no minimum value.

### maxWidth
> Type: `number | null`<br />
> Default: `null`

Maximum width of the column in pixels. Can be `null` for no maximum value.

## Copy pasting
### copyValue
> Type: `({ rowData, rowIndex }) => number | string | null`

A function that returns the value of the copied cell. If the user copies multiple cells at once, this function
will be called multiple times.  It can return a string, a number, or null, but it will always be turned into a string
in the end.


### pasteValue
> Type: `({ rowData, value, rowIndex }) => any`

A function that takes in a row and the `value`  to be pasted, and should return the updated row. If the value should
be ignored, it should still return the unchanged row. The `value` is always a string, except if `prePasteValues` returns
something else, and should therefore be casted to whatever type is needed.

It is recommended to make sure that the `pasteValue` can handle all values returned by `copyValue` otherwise a
user might be able to copy something but not paste it.

### prePasteValues
> Type: `(values: string[]) => any[] | Promise<any[]>`

This function is called right before `pasteValue` with all the data that the user is trying to paste for that column.
This gives you the opportunity to treat the pasted data as a whole and change it before passing it to `pasteValue`.

This is where you would do some asynchronous work (eg. mapping names to actual IDs) and return a Promise.

### deleteValue
> Type: `({ rowData, rowIndex }) => any`

A function that deletes the column value of a row. Used when the user cuts, clears a cell, or deletes a row.

## Rendering
### component
> Type: `CellComponent`

A React component that renders a cell. [See props](cell-components)

### columnData
> Type: `any`

A value to pass to every cell component of the column through the `columnData` prop. Usually used to hold some kind
of options for the column.

For example, to implement a select column you would use `columnData` to pass the choices:
```tsx
const SelectComponent = ({ columnData: choices }) => {
  // Render cell using `choices`
}

const selectColumn = (choices) => ({
  columnData: choices,
  component: SelectComponent,
})

function App() {
  return <DataSheetGrid columns={[
    { ...selectColumn(['Light', 'Dark']), title: 'Theme' }
  ]} />
}
```

### headerClassName
> Type: `string`

CSS class of the header cell.

### cellClassName
> Type: `string | (({ rowData, rowIndex, columnId }) => string | undefined)`

CSS class of each cell of the column. Can be a `string` if the class is the same for all cells, or a function
if you need a different class per row.

## Options
### disabled
> Type: `boolean | (({ rowData, rowIndex }) => boolean)`<br />
> Default: `false`

Disable the entire column by passing `true`, or disable it for specific rows by passing a function. Disabled cells
cannot be edited but their values can still be copied.

Try toggling the "active" column:

<DisableColumns />

```tsx
<DataSheetGrid
  columns={[
    { title: 'Active', /*...*/ },
    { title: 'First name', disabled: ({ rowData }) => !rowData.active, /*...*/ },
    { title: 'Last name', disabled: true, /*...*/ },
  ]}
/>
```

:::note
Notice that in this example you cannot delete a row using the `Del` key, this is because you can only delete empty rows.
This might be problematic depending on your use-case, to solve this issue you can use [`isCellEmpty`](#iscellempty)
and always return true to ignore this column.
:::

### disableKeys
> Type: `boolean`<br />
> Default: `false`

Usually when the user is editing a cell, pressing the up, down, or return key will exit editing mode.
Setting `disableKeys` to `true` will prevent this behavior. This is used when the widget needs to handle the up and
down keys itself (eg. to increase the value, or select a choice). Usually the widget also needs to handle the return
key by calling [stopEditing](cell-components#stopediting).

### keepFocus
> Type: `boolean`<br />
> Default: `false`

When you implement a widget using a portal (ie. a div that is not a direct children of the cell) you might
want the cell to keep focus when the user interacts with that element (even though it is actually
outside of the grid itself). This means that you have to handle the click event and call [stopEditing](cell-components#stopediting)
yourself to release focus.

## Behavior

### isCellEmpty
> Type: `({ rowData, rowIndex }) => boolean`<br />
> Default: `() => false`

When pressing `Del`, a user can only delete empty rows (a user can still delete non-empty rows using a right-click).
A row is considered empty when all its cells are empty. This function allows to customize what is considered
an empty cell.

Because the default value is a function that **always** returns `false` (meaning the cell is never considered empty),
you must implement your own logic to let the user delete rows using the `Del` key.
